package org.yoshiori.hatena.d.keyword;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.yoshiori.commons.security.XmlRpcUtils;
import org.yoshiori.hatena.HatenaException;

/**
 * <p>はてなキーワード自動リンクを行うクラスです.<br/>
 * はてなキーワード自動リンクの詳細については「<a href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%C0%A5%A4%A5%A2%A5%EA%A1%BC%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%BC%AB%C6%B0%A5%EA%A5%F3%A5%AFAPI">はてなダイアリーキーワード自動リンクAPI</a>」こちらをご覧ください。</p>
 * 
 * <p>主な使い方としては<br/>
 * <pre><code> HatenaKeywordAutoLink keyword = new HatenaKeywordAutoLink();
 * keyword.setAClass("hatena_keywod");
 * keyword.setATarget("_blank");
 * keyword.setCname(new HatenaKeywordAutoLink.CategoryName[]{HatenaKeywordAutoLink.CategoryName.HATENA});
 * keyword.setScore(5);
 * String text = keyword.getHatenaSetKeywordLink("はてなダイアリー！！！！");</code></pre><br/>
 * で、キーワード部分を自動的にリンクした文字列を取得できます。<br/>
 * 
 * @author yoshiori
 * @see　<a href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%C0%A5%A4%A5%A2%A5%EA%A1%BC%A5%AD%A1%BC%A5%EF%A1%BC%A5%C9%BC%AB%C6%B0%A5%EA%A5%F3%A5%AFAPI">はてなダイアリーキーワード自動リンクAPI</a>
 */
public class HatenaKeywordAutoLink {

	private static final XmlRpcClient client = XmlRpcUtils.getXmlRpcClient("http://d.hatena.ne.jp/xmlrpc");

	private Integer score;
	private CategoryName[] cname;
	private String aTarget;
	private String aClass;

	/**
	 * @param body キーワードを抽出するテキストを指定します。
	 * @return キーワード部分を自動的にリンクした文字列
	 * @throws XmlRpcException 
	 */
	public String getHatenaSetKeywordLink(String body) {
		if(StringUtils.isEmpty(body)){
			throw new NullPointerException("body is null");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			map.put("body", body.getBytes("utf-8"));
		} catch (UnsupportedEncodingException e) {
			throw new HatenaException(e);
		}
		if(score != null){
			map.put("score", score);
		}
		if(cname != null && cname.length > 0){
			List<String> list = new ArrayList<String>(); 
			for(CategoryName categoryName : cname){
				list.add(categoryName.toString());
			}
			map.put("cname", list);
		}
		if(StringUtils.isNotEmpty(aTarget)){
			map.put("a_target", aTarget);
		}
		if(StringUtils.isNotEmpty(aClass)){
			map.put("a_class", aClass);
		}
		try {
			return (String) client.execute("hatena.setKeywordLink", new Object[]{map});
		} catch (XmlRpcException e) {
			throw new HatenaException(e);
		}
	}
	
	/**
	 * @return the aClass
	 */
	public String getAClass() {
		return aClass;
	}

	/**
	 * @param class1 アンカー(a)タグのtarget属性値を指定します。省略可。例：_blank
	 */
	public void setAClass(String class1) {
		aClass = class1;
	}

	/**
	 * @return the aTarget
	 */
	public String getATarget() {
		return aTarget;
	}

	/**
	 * @param target アンカー(a)タグのtarget属性値を指定します。省略可。例：_blank
	 */
	public void setATarget(String target) {
		aTarget = target;
	}

	/**
	 * @return the cname
	 */
	public CategoryName[] getCname() {
		return cname;
	}

	/**
	 * @param cname キーワードのカテゴリーを指定します。指定があった場合、「一般」と指定されたカテゴリーのキーワードが抽出されます。指定が無かった場合は、全カテゴリーとなります。
     * @see CategoryName
	 */
	public void setCname(CategoryName[] cname) {
		this.cname = cname;
	}

	/**
	 * @return the score
	 */
	public Integer getScore() {
		return score;
	}

	/**
	 * @param score キーワードスコアのしきい値を指定します。指定された値よりもスコアが大きいキーワードのみが抽出されます。省略可。
	 */
	public void setScore(Integer score) {
		this.score = score;
	}

	/**
     * キーワードのカテゴリー
	 * @author yoshiori
	 *
	 */
	public enum CategoryName{
		BOOK("book"), 
		MUSIC("music"), 
		MOVIE("movie"), 
		WEB("web"), 
		ELEC("elec"),
		ANIMAL("animal"),
		ANIME("anime"),
		FOOD("food"),
		SPORTS("sports"),
		GAME("game"),
		COMIC("comic"),
		HATENA("hatena"),
		CLUB("club");
		
        private String categoryName;

        /**
         * @param categoryName
         */
        private CategoryName(String categoryName) {
            this.categoryName = categoryName;
        }

        /*
         * (non-Javadoc)
         * 
         * @see java.lang.Enum#toString()
         */
        public String toString() {
            return categoryName;
        }
	}
}
